from collections import deque
from typing import *

# 他奶奶的傻逼设计，文档也不写，老外写的也他妈很傻逼
# 找到正确办法了，尼玛留作纪念了


def fuck_union(types):
    u = Union[types[0]]
    for x in types:
        u = Union[Union[x], u]
    return u


def to_type_hint(t: Any) -> Any:
    base_types = [int, float, complex, bool, str]
    m = {
        list: List,
        set: Set,
        tuple: Tuple,
        deque: Deque
    }
    if t is None:
        return None
    elif type(t) in base_types:
        return type(t)
    elif type(t) in [list, set,  deque]:
        # empty
        if not t:
            return type(t)
        item_types = list(set(type(v) for v in t))
        # unique item type
        if len(item_types) == 1:
            return m[type(t)][item_types[0]]
        else:
            # shit,trash Union
            return m[type(t)][Union[tuple(item_types)]]
    elif type(t) is tuple:
        # empty
        if not t:
            return Tuple[()]
        elif len(t) < 4:
            return Tuple[tuple(type(v) for v in t)]
        else:
            item_types = list(set(type(v) for v in t))
            if len(item_types) == 1:
                return Tuple[tuple([item_types[0], ...])]
            else:
                return Tuple[Union[tuple(item_types)], ...]

    elif type(t) is dict:
        types = [(type(k), type(v)) for k, v in t.items()]
        k_types = [type(k) for k in t.keys()]
        v_types = [type(v) for v in t.values()]
        if len(set(types)) == 1:
            return Dict[types[0]]
        else:
            return Dict[Union[tuple(k_types)], Union[tuple(v_types)]]


print(to_type_hint({1: 2, 3: 4}))
